//
//  Computer.m
//  AutoPong
//
//  Created by Pierre DUCHENE on 10/12/09.
//  Copyright 2009 Pierre DUCHENE. All rights reserved.
//

#import "Computer.h"
#import "AccelerometerDelegate.h"
#import "Raquette.h"
#import "Block.h"

@implementation Computer

@synthesize controller;
@synthesize mainView;
@synthesize raquette;
@synthesize currentScore;
@synthesize bestScore;

- (id)initWithController:(AutoPongViewController*)aController
{
	if (self = [super init]) {
		self.controller = aController;
		accelerometerDelegate = [[AccelerometerDelegate alloc] init];
		[[UIAccelerometer sharedAccelerometer] setDelegate:accelerometerDelegate];
		blocks = [[NSMutableSet alloc] init];
		timeUntilCreateNewBlock = 0.5;
		currentScore = 0;
		bestScore = 0;
	}
	return self;
}

- (void)runLoop
{
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	[self generateBlocks];
	lastBlockCreationDate = [[NSDate alloc] init];
	// Boucle
	while (true) {
		if (abs([lastBlockCreationDate timeIntervalSinceNow]) > timeUntilCreateNewBlock) {
			[self generateBlocks];
			[lastBlockCreationDate release];
			lastBlockCreationDate = [[NSDate alloc] init];
		}
		[self moveRaquette];
		[self moveBlocks];
		[NSThread sleepForTimeInterval:0.01];
	}
	
	[pool release];
}

- (void)dealloc
{
	[blocks release];
	[lastBlockCreationDate release];
	[super dealloc];
}

- (void)moveRaquette
{
	float x = [accelerometerDelegate x];
	if(x > 0.1) {
		[raquette setFrame:CGRectMake(MIN([raquette frame].origin.x+MIN(floor(x*15),4), 320-[raquette frame].size.width),
									  [raquette frame].origin.y,
									  [raquette frame].size.width,
									  [raquette frame].size.height)];
		[raquette performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
	}
	if(x < -0.1) {
		[raquette setFrame:CGRectMake(MAX([raquette frame].origin.x-MIN(floor(-x*15),4), 0),
									  [raquette frame].origin.y,
									  [raquette frame].size.width,
									  [raquette frame].size.height)];
		[raquette performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
	}
}

- (void)generateBlocks
{
	Block* tmpBlock = [[Block alloc] init];
	[blocks addObject:tmpBlock];
	[mainView addSubview:tmpBlock];
	[tmpBlock setSpeed:(2+random()%5)];
	[tmpBlock setFrame:CGRectMake(random()%((long int)(320.0-([tmpBlock frame].size.width))),
								  [tmpBlock frame].origin.y,
								  [tmpBlock frame].size.width,
								  [tmpBlock frame].size.height)];
}

- (void)moveBlocks
{
	NSMutableSet* blocksToDelete = [[NSMutableSet alloc] init];
	NSEnumerator* blocksEnum = [blocks objectEnumerator];
	
	Block* currentBlock;
	
	while(currentBlock = [blocksEnum nextObject]) {
		int x = [currentBlock frame].origin.x;
		int y = [currentBlock frame].origin.y;
		int width = [currentBlock frame].size.width;
		int height = [currentBlock frame].size.height;
		
		if(y >= 480) {
			[blocksToDelete addObject:currentBlock];
			[currentBlock removeFromSuperview];
			int val = [currentBlock value];
			if (val == -1) {
				currentScore = 0;
			}
			else {
				currentScore = MAX(0, currentScore - val*2);
			}
			
			[controller performSelectorOnMainThread:@selector(updateScore) withObject:nil waitUntilDone:NO];
		}
		else if ( ((y + height) >= ([raquette frame].origin.y)) &&
				  ((y + height) <= ([raquette frame].origin.y + [raquette frame].size.height)) &&
				  ((x + width/2) >= ([raquette frame].origin.x)) &&
				  ((x + width/2) <= ([raquette frame].origin.x + [raquette frame].size.width)) ) {
			[blocksToDelete addObject:currentBlock];
			[currentBlock removeFromSuperview];
			int val = [currentBlock value];
			if (val == -1) {
				currentScore += 10;
			}
			else {
				currentScore += val;
			}
			if(currentScore > bestScore) {
				bestScore = currentScore;
			}
			[controller performSelectorOnMainThread:@selector(updateScore) withObject:nil waitUntilDone:NO];
		}
		else {
			[currentBlock setFrame:CGRectMake(x,
											  y + [currentBlock speed],
											  [currentBlock frame].size.width,
											  height)];
			[currentBlock performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
		}
	}
	
	NSEnumerator* blocksToDelEnum = [blocksToDelete objectEnumerator];
	while(currentBlock = [blocksToDelEnum nextObject]) {
		[blocks removeObject:currentBlock];
	}
	
	[blocksToDelete release];
}

@end
